package main

import (
	"bufio"
	"fmt"
	"io"
	"os"
	"strconv"
	"strings"
)

//应用实例：
/*
1、使用稀疏数组，来保存类似前面的二维数组（棋盘，地图等待）
2、把稀疏数组存盘，并且可以重新恢复原来的二维数组
*/

func main() {
	//1、先创建一个原始数组
	var chessMap [11][11]int
	chessMap[1][2] = 1 //代表黑棋
	chessMap[2][3] = 2 //代表白棋

	//2、遍历看看原始数组
	for _, v := range chessMap {
		for _, v2 := range v {
			fmt.Printf("%d\t", v2)
		}
		fmt.Println()
	}

	//3、将该数组转成稀疏数组，通过结构体来实现存每个特别数据
	//思路：遍历chessMap，如果发现有一个元素的值不为零就创建node结构体，然后再放入到切片中
	var sparsearray []ValNode
	//标准的稀疏数组最开始应该是表示记录原始二位数组的规模（行、列、默认值）
	node := ValNode{
		row: 11,
		col: 11,
		val: 0,
	}
	sparsearray = append(sparsearray, node)
	for i, v := range chessMap {
		for j, v2 := range v {
			if v2 != 0 {
				node = ValNode{
					row: i,
					col: j,
					val: v2,
				}
				sparsearray = append(sparsearray, node)
			}
		}
	}

	//将稀疏数组逐行存入文件中 (存盘！)
	file, err := os.OpenFile("d:/uploadfiles/chess.data", os.O_WRONLY|os.O_CREATE, 668)
	defer file.Close()
	if err != nil {
		fmt.Println("file open fail err:", err)
		return
	}
	writer := bufio.NewWriter(file)
	for _, vnode := range sparsearray {
		str := fmt.Sprintf("%d %d %d\n", vnode.row, vnode.col, vnode.val)
		writer.WriteString(str)
	}
	writer.Flush()

	//读取文件，重新恢复
	file, err = os.Open("d:/uploadfiles/chess.data")
	if err != nil {
		fmt.Println("file open fail err:", err)
		return
	}
	reader := bufio.NewReader(file)
	str, err := reader.ReadString('\n')
	strslice := strings.Split(str, " ")
	row, _ := strconv.Atoi(strslice[0])
	col, _ := strconv.Atoi(strslice[1])
	val, _ := strconv.Atoi(strslice[2])
	fmt.Println(row, col, val)
	chessMap2 := make([][]int, row)
	for i := 0; i < row; i++ {
		chessMap2[i] = make([]int, col)
	}
	for {
		str, err = reader.ReadString('\n')
		if err == io.EOF {
			break
		}
		str = strings.Trim(str, "\r\n")
		strslice = strings.Split(str, " ")
		row, _ = strconv.Atoi(strslice[0])
		col, _ = strconv.Atoi(strslice[1])
		val, _ = strconv.Atoi(strslice[2])
		chessMap2[row][col] = val
	}

	for _, v := range chessMap2 {
		for _, v2 := range v {
			fmt.Printf("%d\t", v2)
		}
		fmt.Println()
	}

}

type ValNode struct {
	row int
	col int
	val int
}
